/*
 * VHAssociationSeasonOverviewGrid.java
 * Created on 27 sept. 2009
 *
 * VirtualHockey Internet Platform
 * http://code.google.com/p/virtualhockey/
 *
 * Copyright (c) 2005-2009, Jens and Jan Janke (VirtualHockey Project)
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see http://www.gnu.org/licenses/.
 */

package com.hockeo.vhweb.client.ui.widget;

import java.util.ArrayList;
import java.util.List;

import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.Style.SortDir;
import com.extjs.gxt.ui.client.store.GroupingStore;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
import com.extjs.gxt.ui.client.widget.grid.ColumnData;
import com.extjs.gxt.ui.client.widget.grid.ColumnModel;
import com.extjs.gxt.ui.client.widget.grid.Grid;
import com.extjs.gxt.ui.client.widget.grid.GridCellRenderer;
import com.extjs.gxt.ui.client.widget.grid.GridGroupRenderer;
import com.extjs.gxt.ui.client.widget.grid.GroupColumnData;
import com.extjs.gxt.ui.client.widget.grid.GroupingView;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.google.gwt.i18n.client.NumberFormat;
import com.hockeo.vhweb.client.VHMain;
import com.hockeo.vhweb.client.mvc.VHController;
import com.hockeo.vhweb.client.res.VHResConstants;
import com.hockeo.vhweb.client.rpc.VHRpcCallback;
import com.hockeo.vhweb.client.rpc.VHRpcResultReceiver;
import com.hockeo.vhweb.client.ui.menu.VHClubInfoContextMenu;
import com.hockeo.vhweb.client.ui.menu.VHGridContextMenu;
import com.hockeo.vhweb.client.utils.VHJsData;
import com.hockeo.vhweb.client.utils.enums.VHJsContestType;

/**
 * Displays a season summary for the given association and season.
 *
 * @version $Id$
 * @author jjanke
 */
public class VHAssociationSeasonOverviewGrid extends LayoutContainer implements VHRpcResultReceiver<List<VHJsData>>
{
  private static final String           COL_CSS             = "CSS";
  private static final String           COL_RESULT_ICON     = "RESULT_ICON";
  private static final String           COL_CONTEST_RESULT  = "CONTEST_RESULT";
  private static final String           COL_CONTEST_TYPE    = "contest_type";
  private static final String           COL_RECORD_ORDER    = "record_order";
  private static final String           COL_CATEGORY_HEADER = "category_header";
  private final VHGridContextMenu       d_ctxmenu;
  private final GroupingStore<VHJsData> d_store;
  private Grid<VHJsData>                d_grid;
  private VHJsData                      d_season            = null;
  private VHJsData                      d_assoc             = null;

  /**
   * Builds a new season overview grid.
   *
   * @param controller the VH display controller
   * @param season the season for which to display the overview (leave <code>null</code>
   *          to retrieve data for the current season)
   * @param assoc the association for which to display the overview
   */
  public VHAssociationSeasonOverviewGrid( VHController controller, VHJsData season, VHJsData assoc )
  {
    d_season = season;
    d_assoc = assoc;
    d_store = new GroupingStore<VHJsData>();

    setLayout( new FitLayout() );
    buildGrid();
    add( d_grid );

    d_ctxmenu = new VHClubInfoContextMenu( controller, d_grid, "club_" );

    loadData();
  }

  public void setRpcData( List<VHJsData> listRecords, String strPurpose )
  {
    d_store.removeAll();

    // Iterate over all records and add required extra information
    //
    for ( VHJsData record : listRecords )
    {
      // add information about the contest type (league, cup, cl or wl)
      //
      String strContestId = record.getString( "contest_id" );
      String strRank = String.valueOf( record.getInt( "rank" ) );

      while ( strRank.length() < 3 )
        strRank = "0" + strRank;

      if ( strContestId.equals( "EU1" ) )
      {
        record.set( COL_CONTEST_TYPE, VHJsContestType.CL.name() );
        record.set( COL_CATEGORY_HEADER, VHMain.getConstants().intContests() );
        record.set( COL_RECORD_ORDER, "11" + strRank );
        record.set( COL_CONTEST_RESULT, record.getString( "reachedRound_translated" ) );
        record.set( COL_CSS, "" );
      }
      else if ( strContestId.equals( "EU2" ) )
      {
        record.set( COL_CONTEST_TYPE, VHJsContestType.WL.name() );
        record.set( COL_CATEGORY_HEADER, VHMain.getConstants().intContests() );
        record.set( COL_RECORD_ORDER, "12" + strRank );
        record.set( COL_CONTEST_RESULT, record.getString( "reachedRound_translated" ) );
        record.set( COL_CSS, "" );
      }
      else if ( record.getType().equals( "GClubLeagueHistoryRecord" ) )
      {
        record.set( COL_CONTEST_TYPE, VHJsContestType.LEAGUE.name() );
        record.set( COL_CATEGORY_HEADER, VHMain.getMessages().leagueGroupHeader(
            record.getString( "contest_id_translated" ), record.getInt( "contest_category" ) ) );
        record.set( COL_RECORD_ORDER, "3" + record.getInt( "contest_category" ) + strRank );

        String strContestResult = null;

        if ( record.getBoolean( "qualifiedEU1" ) )
        {
          strContestResult = VHMain.getConstants().qualifiedForChampionsLeague();
          record.set( COL_CSS, "PROMOTED_1" );
        }
        else if ( record.getBoolean( "qualifiedEU2" ) )
        {
          strContestResult = VHMain.getConstants().qualifiedForWorldLeague();
          record.set( COL_CSS, "PROMOTED_2" );
        }
        else if ( record.getBoolean( "promoted" ) )
        {
          strContestResult = VHMain.getConstants().promoted();
          record.set( COL_CSS, "PROMOTED_1" );
        }
        else if ( record.getBoolean( "relegated" ) )
        {
          strContestResult = VHMain.getConstants().relegated();
          record.set( COL_CSS, "RELEGATED" );
        }

        record.set( COL_CONTEST_RESULT, strContestResult );
      }
      else
      {
        record.set( COL_CONTEST_TYPE, VHJsContestType.CUP.name() );
        record.set( COL_CATEGORY_HEADER, VHMain.getMessages().cupGroupHeader(
            record.getString( "contest_id_translated" ) ) );
        record.set( COL_RECORD_ORDER, "20" + strRank );
        record.set( COL_CONTEST_RESULT, record.getString( "reachedRound_translated" ) );
        record.set( COL_CSS, "" );
      }

      // result icon
      //
      if ( record.getType().equals( "GClubLeagueHistoryRecord" )
          && ( record.getBoolean( "promoted" ) || record.getBoolean( "relegated" ) ) )
      {
        String strIcon = null;

        if ( record.getBoolean( "promoted" ) )
          strIcon = "images/picto/rank_promoted.gif";
        else if ( record.getBoolean( "relegated" ) )
          strIcon = "images/picto/rank_relegated.gif";

        record.set( COL_RESULT_ICON, strIcon );
      }
      else
      {
        String strIcon = null;

        switch ( record.getInt( "rank" ) )
        {
          case 1:
            strIcon = "images/picto/medal_gold.png";
            break;
          case 2:
            strIcon = "images/picto/medal_silver.png";
            break;
          case 3:
            strIcon = "images/picto/medal_bronze.png";
            break;
          default:
            strIcon = "images/picto/rank_midfield.gif";
        }

        record.set( COL_RESULT_ICON, strIcon );
      }
    }

    d_store.add( listRecords );

    // grouping and sorting
    //
    d_store.groupBy( COL_CATEGORY_HEADER );
    d_store.sort( COL_RECORD_ORDER, SortDir.ASC );
  }

  /**
   * Sets the season for which to display data and asks the table to reload itself.
   */
  public void setSeason( VHJsData season )
  {
    if ( d_season != null && d_season.getInt( "id" ) == season.getInt( "id" ) )
      return;

    d_season = season;
    loadData();
  }

  public VHJsData getSeason()
  {
    return d_season;
  }

  /**
   * Sets the association for which to display data and asks the table to reload itself.
   */
  public void setAssociation( VHJsData assoc )
  {
    if ( d_assoc != null && d_assoc.getId().equals( assoc.getId() ) )
      return;

    d_assoc = assoc;
    loadData();
  }

  public VHJsData getAssocation()
  {
    return d_assoc;
  }

  /**
   * Asks the server to return refreshed data.
   */
  private void loadData()
  {
    VHController.getBaseDataService().getCountrySeasonOverviewRecords( VHController.getLocale(), d_assoc.getId(),
        ( d_season != null ? d_season.getInt( "id" ) : null ), new VHRpcCallback<List<VHJsData>>( this, null ) );
  }

  private void buildGrid()
  {
    final NumberFormat numberFormat = NumberFormat.getFormat( "0.00" );
    GridCellRenderer<VHJsData> renderer = new GridCellRenderer<VHJsData>() {
      public String render( VHJsData data, String strProperty, ColumnData config, int rowIndex, int colIndex,
          ListStore<VHJsData> store, Grid<VHJsData> grid )
      {
        config.css = data.getString( COL_CSS );

        if ( strProperty.equals( "club_country" ) )
        {
          String strTooltip = data.getString( "club_country_name" );
          return "<img src='images/flags/16x16/" + data.getString( "club_country" ) + ".png' title='" + strTooltip + "'/>";
        }
        else if ( strProperty.equals( "club_name" ) && !data.getString( COL_CONTEST_TYPE ).equals( VHJsContestType.LEAGUE.name() ) )
          return data.getString( "club_name" ) + " (" + data.getInt( "club_league_category" ) + ")";
        else if ( strProperty.equals( COL_CONTEST_TYPE ) )
          return "<img src='images/contests/" + data.getString( strProperty ).toLowerCase() + "_16.png'/>";
        else if ( strProperty.equals( COL_RESULT_ICON ) )
          return "<img src='" + data.getString( strProperty ) + "'/>";
        else if ( strProperty.equals( COL_RECORD_ORDER ) )
          return data.getString( COL_CONTEST_RESULT );
        else if ( strProperty.equals( "pointsPercentage" ) )
          return numberFormat.format( data.getDouble( strProperty ) * 100.0 );
        else if ( strProperty.equals( "pointsECR" ) )
          return numberFormat.format( data.getDouble( strProperty ) );

        return String.valueOf( data.get( strProperty ) );
      }
    };

    // Column definitions
    //
    VHResConstants constants = VHMain.getConstants();
    ArrayList<ColumnConfig> listCols = new ArrayList<ColumnConfig>();
    ColumnConfig col;

    col = new ColumnConfig();
    col.setId( COL_CATEGORY_HEADER );
    col.setWidth( 0 );
    col.setAlignment( HorizontalAlignment.RIGHT );
    col.setResizable( false );
    col.setMenuDisabled( true );
    col.setSortable( false );
    col.setHidden( true );
    listCols.add( col );

    col = new ColumnConfig();
    col.setId( COL_CONTEST_TYPE );
    col.setHeader( constants.contestTypeAbbrev() );
    col.setToolTip( constants.contestType() );
    col.setWidth( 26 );
    col.setAlignment( HorizontalAlignment.CENTER );
    col.setResizable( false );
    col.setMenuDisabled( true );
    col.setSortable( true );
    col.setRenderer( renderer );
    listCols.add( col );

    col = new ColumnConfig();
    col.setId( COL_RESULT_ICON );
    col.setHeader( constants.rankTypeAbbrev() );
    col.setToolTip( constants.rankType() );
    col.setWidth( 26 );
    col.setAlignment( HorizontalAlignment.CENTER );
    col.setResizable( false );
    col.setMenuDisabled( true );
    col.setSortable( false );
    col.setRenderer( renderer );
    listCols.add( col );

    col = new ColumnConfig();
    col.setId( "rank" );
    col.setHeader( constants.rankAbbrev() );
    col.setToolTip( constants.rank() );
    col.setWidth( 28 );
    col.setAlignment( HorizontalAlignment.RIGHT );
    col.setResizable( false );
    col.setRenderer( renderer );
    col.setMenuDisabled( true );
    listCols.add( col );

    col = new ColumnConfig();
    col.setId( COL_RECORD_ORDER );
    col.setHeader( constants.reachedRound() );
    col.setWidth( 120 );
    col.setAlignment( HorizontalAlignment.LEFT );
    col.setResizable( true );
    col.setMenuDisabled( true );
    col.setSortable( false );
    col.setRenderer( renderer );
    col.setMenuDisabled( true );
    listCols.add( col );

    col = new ColumnConfig();
    col.setId( "club_country" );
    col.setHeader( constants.countryAbbrev() );
    col.setToolTip( constants.country() );
    col.setWidth( 26 );
    col.setRenderer( renderer );
    col.setAlignment( HorizontalAlignment.CENTER );
    col.setResizable( false );
    col.setMenuDisabled( true );
    listCols.add( col );

    col = new ColumnConfig();
    col.setId( "club_name" );
    col.setHeader( constants.clubName() );
    col.setWidth( 180 );
    col.setRenderer( renderer );
    col.setMenuDisabled( true );
    listCols.add( col );

    col = new ColumnConfig();
    col.setId( "numMatches" );
    col.setHeader( constants.numMatchesAbbrev() );
    col.setToolTip( constants.numMatches() );
    col.setWidth( 30 );
    col.setAlignment( HorizontalAlignment.RIGHT );
    col.setMenuDisabled( true );
    col.setRenderer( renderer );
    listCols.add( col );

    col = new ColumnConfig();
    col.setId( "numPoints" );
    col.setHeader( constants.numPointsAbbrev() );
    col.setToolTip( constants.numPoints() );
    col.setWidth( 30 );
    col.setAlignment( HorizontalAlignment.RIGHT );
    col.setMenuDisabled( true );
    col.setRenderer( renderer );
    listCols.add( col );

    col = new ColumnConfig();
    col.setId( "numWins" );
    col.setHeader( constants.numWinsAbbrev() );
    col.setToolTip( constants.numWins() );
    col.setWidth( 30 );
    col.setAlignment( HorizontalAlignment.RIGHT );
    col.setMenuDisabled( true );
    col.setRenderer( renderer );
    listCols.add( col );

    col = new ColumnConfig();
    col.setId( "numWinsOT" );
    col.setHeader( constants.numWinsOtAbbrev() );
    col.setToolTip( constants.numWinsOt() );
    col.setWidth( 30 );
    col.setAlignment( HorizontalAlignment.RIGHT );
    col.setMenuDisabled( true );
    col.setRenderer( renderer );
    listCols.add( col );

    col = new ColumnConfig();
    col.setId( "numLossesOT" );
    col.setHeader( constants.numLossesOtAbbrev() );
    col.setToolTip( constants.numLossesOt() );
    col.setWidth( 30 );
    col.setAlignment( HorizontalAlignment.RIGHT );
    col.setMenuDisabled( true );
    col.setRenderer( renderer );
    listCols.add( col );

    col = new ColumnConfig();
    col.setId( "numLosses" );
    col.setHeader( constants.numLossesAbbrev() );
    col.setToolTip( constants.numLosses() );
    col.setWidth( 30 );
    col.setAlignment( HorizontalAlignment.RIGHT );
    col.setMenuDisabled( true );
    col.setRenderer( renderer );
    listCols.add( col );

    col = new ColumnConfig();
    col.setId( "pointsPercentage" );
    col.setHeader( constants.pointsPctAbbrev() );
    col.setToolTip( constants.pointsPct() );
    col.setWidth( 40 );
    col.setRenderer( renderer );
    col.setAlignment( HorizontalAlignment.RIGHT );
    col.setMenuDisabled( true );
    col.setRenderer( renderer );
    listCols.add( col );

    col = new ColumnConfig();
    col.setId( "pointsECR" );
    col.setHeader( constants.pointsECRAbbrev() );
    col.setToolTip( constants.pointsECR() );
    col.setWidth( 40 );
    col.setRenderer( renderer );
    col.setAlignment( HorizontalAlignment.RIGHT );
    col.setMenuDisabled( true );
    col.setRenderer( renderer );
    listCols.add( col );

    final ColumnModel cm = new ColumnModel( listCols );

    // Header cells with tooltips
    //
    GroupingView view = new GroupingView();

    view.setForceFit( true );
    view.setGroupRenderer( new GridGroupRenderer() {
      public String render( GroupColumnData data )
      {
        VHJsData recordFirst = (VHJsData) data.models.get( 0 );

        return recordFirst.getString( COL_CATEGORY_HEADER );
      }
    } );

    // Grid
    //
    d_grid = new Grid<VHJsData>( d_store, cm );
    d_grid.setView( view );
    d_grid.setAutoExpandColumn( "club_name" );
    d_grid.setHideHeaders( false );
    d_grid.setStripeRows( true );
    d_grid.setBorders( true );
    d_grid.setAutoWidth( true );
  }
}
